import datetime

from django.db.models import Count
from rest_framework.generics import GenericAPIView
from rest_framework.views import APIView

from app.models import WxUser, UserAddress
from jiaozi.base_view import JwtListCreateAPIView, JwtListAPIView, JwtCreateAPIView
from jiaozi.utils import APIResponse, get_user_id, MmFilter, make_wx_pay_order, get_client_ip
from money.models import PayRecord
from product.models import ProductSales
from sales.serializers import *


class ProductSalesOrderFilter(MmFilter):
    class Meta:
        model = ProductSalesOrder
        fields = {
            'order_number': ['contains'],
            'customer_notes': ['contains'],
            'is_payed': ['exact'],
            'is_send': ['exact'],
            'order_state': ['exact']
        }


class ProductSalesOrderListView(JwtListAPIView):
    """
    get:
        用户订单的查询
    post:
        用户订单的创建
    """
    serializer_class = ProductSalesOrderSerializer
    filterset_class = ProductSalesOrderFilter
    queryset = None
    pagination_class = None

    def get_queryset(self):
        queryset = ProductSalesOrder.objects.none()
        user_id = get_user_id(self)
        if user_id:
            queryset = ProductSalesOrder.objects.filter(user_id=user_id, is_show=True)
        return queryset


class OrderCreateView(JwtCreateAPIView):
    """
    post:
        用户提交购买订单, order_items [{"product_sales": 2, "amount": 1}]
    """

    serializer_class = OrderCreateSerializer

    @staticmethod
    def _union_order_items(order_items):
        res_dict = dict()
        for row in order_items:
            product_sales = row.get('product_sales')
            if isinstance(product_sales, dict):
                product_sales = product_sales.get('id')
            res_dict[product_sales] = row.get('amount')
        return res_dict

    def create(self, request, *args, **kwargs):
        print('request.data', request.data)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        new_data = dict()

        # 添加默认值 user 为提交的用户
        user_id = get_user_id(self)
        new_data['user_id'] = user_id

        openid = WxUser.objects.get(pk=user_id).openid
        if not openid:
            return APIResponse(status=200, code=400, message='账号未登录')

        # 获取 address_id
        new_data['address_id'] = None
        address_id = request.data.get('address_id')
        if address_id:
            user_address = UserAddress.objects.filter(pk=address_id).order_by('pk').first()
            if user_address:
                if user_address.user_id == user_id:
                    new_data['address_id'] = address_id
        if not new_data['address_id']:
            user_address = UserAddress.objects.filter(user_id=user_id).order_by('pk').first()
            if user_address:
                new_data['address_id'] = user_address.pk

        # 获取用户备注
        new_data['customer_notes'] = request.data.get('customer_notes')

        order_items = request.data.get('order_items')
        if not order_items:
            return APIResponse(code=400, status=400, message='请提供 order_items')

        new_order_items = list()
        total_price = 0

        for order_item in order_items:
            product_sales_id = order_item.get('product_sales')
            if product_sales_id:
                # product_sales = model_data_from_cache(ProductSales, pk=product_sales_id, force_update=True)
                product_sales = ProductSales.objects.filter(pk=product_sales_id).first()
                if product_sales:
                    if product_sales.amount_left <= 0:
                        return APIResponse(code=400, status=200, message='你已被其他玩家秒杀')
                    print('product_sales', product_sales)
                    # 获取商品的价格
                    price_show = product_sales.price_show
                    order_item['price_initial'] = price_show
                    order_item['price_payed'] = price_show
                    amount = order_item.get('amount')
                    total_price += round(int(amount) * float(price_show), 2)
                    new_order_items.append(order_item)

        if not new_order_items:
            return APIResponse(code=400, status=200, message='你已被其他玩家秒杀')
        if not total_price:
            return APIResponse(code=400, status=200, message='你已被其他玩家秒杀')

        # 写入金额
        new_data['price_initial'] = total_price
        new_data['price_payed'] = total_price

        # 创建订单
        fields = ['user_id', 'address_id', 'price_initial', 'price_payed']
        filter_data = dict()
        for f in fields:
            filter_data[f] = new_data.get(f)
        product_sales_order = ProductSalesOrder.objects.filter(
            **filter_data,
            is_payed=False,
            is_show=True
        ).order_by('-pk').first()
        if product_sales_order:
            res_dict_original = self._union_order_items(product_sales_order.order_items)
            res_dict_current = self._union_order_items(new_order_items)
            if not res_dict_original == res_dict_current:
                product_sales_order = None
        if not product_sales_order:
            product_sales_order = ProductSalesOrder.objects.create(**new_data)
            product_sales_order.order_items = new_order_items
            total_fee = str(int(100 * total_price))
            print('total_fee', total_fee)
            pay_record = PayRecord.objects.create(
                sales_order_id=product_sales_order.pk,
                pay_type=2,
                user_id=user_id,
                openid=openid,
                body='购买商品',
                total_fee=total_fee,
                pay_time=datetime.datetime.now()
            )
            product_sales_order.pay_record = pay_record
            product_sales_order.save()
        else:
            pay_record = product_sales_order.pay_record
        # 构建支付订单
        pay_info = make_wx_pay_order(
            openid,
            pay_record.out_trade_no,
            pay_record.total_fee,
            body=pay_record.body,
            client_ip=get_client_ip(request)
        )
        res_data = {'pay_info': pay_info, 'order_items': order_items, 'total_price': total_price}
        return APIResponse(data=res_data)


class OrderDeleteView(GenericAPIView):
    """
    用户取消付款
    """

    serializer_class = OrderDeleteSerializer

    def post(self, request):
        user_id = get_user_id(self)
        sales_id = request.data.get('sales_id')
        ProductSalesOrder.objects.filter(user_id=user_id, pk=sales_id).update(is_show=False)
        return APIResponse(data='ok')


class OrderCompleteView(GenericAPIView):
    """
    用户确认收货
    """

    serializer_class = OrderDeleteSerializer

    def post(self, request):
        user_id = get_user_id(self)
        sales_id = request.data.get('sales_id')
        ProductSalesOrder.objects.filter(user_id=user_id, pk=sales_id).update(order_state=4)
        return APIResponse(data='ok')


class OrderStateView(GenericAPIView):
    pagination_class = None
    filter_backends = []
    permission_classes = ()

    def get(self, request):
        user_id = get_user_id(self)
        order_states = ProductSalesOrder.objects.filter(
            is_show=True,
            user_id=user_id
        ).values(
            'order_state'
        ).annotate(
            s=Count('order_state')
        ).order_by(
            'order_state'
        )
        user_order_state = dict()

        print(order_states)

        order_state_dict = dict(order_state_choices)

        for order_state in order_states:
            user_order_state[order_state['order_state']] = order_state['s']

        for order_state in order_state_choices:
            if order_state[0] not in user_order_state:
                user_order_state[order_state[0]] = 0

        res_data = {
            'user_order_state': user_order_state,
            'order_state_dict': order_state_dict
        }
        return APIResponse(data=res_data)

